/*
 * Copyright (C) 2018 The Asiainfo-Ability Authors
 *
 *      Licensed under the Apache License, Version 2.0 (the "License");
 *      you may not use this file except in compliance with the License.
 *      You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 *      Unless required by applicable law or agreed to in writing, software
 *      distributed under the License is distributed on an "AS IS" BASIS,
 *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *      See the License for the specific language governing permissions and
 *      limitations under the License.
 */

package org.asiainfo.ability.gateway.context;


import org.asiainfo.ability.base.concurrent.SeqPool;
import org.asiainfo.ability.base.utils.SeqUtils;
import org.asiainfo.ability.base.utils.Sequence;
import org.asiainfo.ability.base.utils.StringUtils;
import org.asiainfo.ability.base.vo.CalleeTrace;
import org.asiainfo.ability.base.vo.CallerTrace;
import org.asiainfo.ability.base.vo.Record;
import org.asiainfo.ability.gateway.custom.CustomHttpServletRequest;
import org.asiainfo.ability.gateway.model.Ability;
import org.asiainfo.ability.gateway.model.User;
import org.asiainfo.ability.gateway.model.UserAbility;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Author: visen
 * @Date: 2018/1/22
 * @Description:
 */
public class AbilityRequestContext {

    public static final String CONTEXT_KEY = "abilityRequestContext";
    private static final String TRACE_ID = "X-Trace-Id";
    private static final String BIZ_ID = "X-Biz-Id";
    private static final String BIZ_ID_IN = "bizId";
    private CallerTrace callerTrace;
    /** sequence utils */

    private Ability ability;
    private User user;
    private UserAbility userAbility;



    private HttpServletRequest request;
    private HttpServletResponse response;

    private AbilityRequestContext(HttpServletRequest request
            ,HttpServletResponse response){
        this.request = request;
        this.response = response;
        callerTrace = new CallerTrace();
        setRequestTraceId(request);
        callerTrace.setBeginTime(System.currentTimeMillis());


    };
    public Ability getAbility() {
        return ability;
    }

    public void setAbility(Ability ability) {
        callerTrace.setApi(ability.getName());
        callerTrace.setServiceName(ability.getServiceName());
        this.ability = ability;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
        callerTrace.setClientId(user.getClientId());
    }

    public UserAbility getUserAbility() {
        return userAbility;
    }

    public void setUserAbility(UserAbility userAbility) {
        this.userAbility = userAbility;
    }

    public static AbilityRequestContext createContext(HttpServletRequest request
            ,HttpServletResponse response) {
        return new AbilityRequestContext(request, response);
    }



    public int getTimeout() {
        if(userAbility != null && userAbility.getTimeout() > 0) {
            return userAbility.getTimeout();
        }
        return ability.getTimeout();
    }


    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

    public void setRequestTraceId(HttpServletRequest request) {
        callerTrace.setId(String.valueOf(SeqPool.tracesSeq().id()));
        callerTrace.setTraceId(callerTrace.getId());
        callerTrace.setBizId(request.getHeader(BIZ_ID_IN));
        if(StringUtils.isBlank(callerTrace.getBizId())) {
            callerTrace.setBizId(callerTrace.getId());
        }
        ((CustomHttpServletRequest)request).putHeader(TRACE_ID, callerTrace.getTraceId());
        ((CustomHttpServletRequest)request).putHeader(BIZ_ID, callerTrace.getBizId());

    }


    public void release() {
        this.ability = null;
        this.userAbility = null;
        this.user = null;
    }

    public CallerTrace getCallerTrace() {
        return callerTrace;
    }

    public void setRecord(Record record) {
        this.callerTrace = callerTrace;
    }
}
